package com.ruoyi.core.config.wx;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.domain.model.WxUser;
import com.ruoyi.common.enums.DeviceType;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.core.config.utils.WxUtil;
import com.ruoyi.core.config.vo.LoginVo;
import com.ruoyi.core.domain.bo.UserBo;
import com.ruoyi.core.domain.vo.UserVo;
import com.ruoyi.core.service.IUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 小程序登录鉴权
 */
@RequestMapping("core/wx")
@RestController
@RequiredArgsConstructor
@Slf4j
@Validated
public class WxMaLoginController extends BaseController {

    private final WxMaService wxMaService;

    private final IUserService userService;

    /**
     * 小程序登录接口
     * @param appid
     * @param code
     * @return
     */
    @SaIgnore
    @GetMapping("/login")
    public R<LoginVo> login(@NotBlank(message = "Appid不能为空") String appid, @NotBlank(message = "code不能为空") String code) {

        //通过缓存 判断用户
        UserVo userVo = WxUtil.getUserVoByToken();
        if (ObjectUtil.isNotNull(userVo)) {
            //刷新缓存，
            WxUtil.refreshWxUser(userVo, false);
            return WxUtil.authMsg(userVo);
        }
        // 根据appid和code获取session
        WxMaJscode2SessionResult session = getSession(appid, code);
        String openId = session.getOpenid();
        // String sessionKey = session.getSessionKey();

        //根据openid查询数据库是否有该用户，
        userVo = userService.getByOpenId(openId);
        if (ObjectUtil.isNull(userVo)) {
            //无用户信息保存到数据库
            userVo = userService.setWxUser("", openId, "1", "", "");
            //登录缓存
            WxUtil.refreshWxUser(userVo, true);
            return R.fail("首次登录未授权", new LoginVo(StpUtil.getTokenValue(), userVo, "1"));
        }
        //有用户信息直接登录
        WxUtil.refreshWxUser(userVo, true);

        return WxUtil.authMsg(userVo);

    }

    /**
     * 小程序授权
     * @param bo
     * @return
     */
    @PostMapping("auth")
    public R<Void> auth(@RequestBody UserBo bo) {
        if (StringUtils.isBlank(bo.getNickname()) || StringUtils.isBlank(bo.getAvatar())) {
            return R.fail("参数不全");
        }
        Long userId = getUserId();
        UserVo userVo = userService.queryById(userId);
        if (ObjectUtil.isNull(userVo)) {
            return R.fail("授权有误");
        }
        UserBo userBo = BeanUtil.toBean(userVo, UserBo.class);
        userBo.setNickname(bo.getNickname());
        userBo.setAvatar(bo.getAvatar());
        userService.updateByBo(userBo);
        //刷新缓存
        WxUtil.refreshWxUser(BeanUtil.toBean(userBo, UserVo.class), false);
        return R.ok("授权成功！");
    }

    /**
     * 更新获取用户信息
     * @return
     */
    @RepeatSubmit// 防止重复提交
    @GetMapping("getUserInfo")
    public R<UserVo> getUserInfo() {
        Long userId = getUserId();
        UserVo userVo = userService.queryById(userId);
        if(ObjectUtil.isNull(userVo)){
            return fail("用户信息不存在");
        }
        WxUtil.refreshWxUser(userVo,false);
        return ok("更新获取成功",userVo);
    }


    //根据appid和code获取session
    private WxMaJscode2SessionResult getSession(String appid, String code) {
        if (!wxMaService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }
        try {
            return wxMaService.getUserService().getSessionInfo(code);
        } catch (WxErrorException e) {
            throw new ServiceException("微信接口异常");
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
    }
}
